<template>
    <el-card style="height: 80px;">
        <el-form :inline="true" class="form">
            <el-form-item label="用户名:">
                <el-input placeholder="请你输入搜索用户名" v-model="keyword"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" size="default" :disabled="keyword?false:true" @click="search">搜索</el-button>
                <el-button type="primary" size="default" @click="reset">重置</el-button>
            </el-form-item>
        </el-form>
    </el-card>
    <el-card style="margin: 10px 0px;">
        <el-button type="primary" size="default" @click="addUser">添加用户</el-button>
        <el-button type="primary" size="default" :disabled="deleteIdArr.length?false:true" @click="deleteSelectUser">批量删除</el-button>
        <!-- table展示用户信息 -->
        <el-table @selection-change="selectChange" style="margin: 10px 0px;" border :data="userArr">
            <el-table-column type="selection" align="center"></el-table-column>
            <el-table-column label="#" align="center" type="index"></el-table-column>
            <el-table-column label="ID" align="center" prop="id"></el-table-column>
            <el-table-column label="用户名字" align="center" prop="username"></el-table-column>
            <el-table-column label="用户名称" align="center" prop="name" show-overflow-tooltip></el-table-column>
            <el-table-column label="用户角色" align="center" prop="roleName" show-overflow-tooltip></el-table-column>
            <el-table-column label="创建时间" align="center" prop="createTime" show-overflow-tooltip></el-table-column>
            <el-table-column label="更新时间" align="center" prop="updateTime" show-overflow-tooltip></el-table-column>
            <el-table-column label="操作" width="300px" align="center"> 
                <!-- row是每个已有用户 -->
                <template #="{row,index}">
             <el-button type="primary" size="small" icon="User" @click="setRole(row)">分配角色</el-button>
             <el-button type="primary" size="small" icon="Edit" @click="updateUser(row)">编辑</el-button>
            <el-popconfirm :title="`你确定要删除${row.username}?`" width="260px" @confirm="deleteUser(row.id)">
             <template #reference>
                <el-button type="primary" size="small" icon="Delete">删除</el-button>
             </template>
            </el-popconfirm>
                </template>
            </el-table-column>
        </el-table>
        <!-- 分页器 -->
        <el-pagination v-model:current-page="pageNo" v-model:page-size="pageSize" :page-sizes="[5, 7, 9, 11]"
            :background="true" layout="prev, pager, next, jumper,->,sizes,total" :total="total" @current-change="getHasUser" @size-change="handler"/>
    </el-card>
    <!-- 抽屉结构:完成添加新的用户账号|更新已有的用户信息 -->
    <el-drawer v-model="drawer">
    <template #header>
        <!-- 头部标题是动态的：添加用户   修改用户 -->
      <h4>{{ userParams.id ? '更新用户':'添加用户' }}</h4>
    </template>
    <template #default>
        <!-- 告诉el-form组件数据收集到哪里 -->
      <el-form :model="userParams" :rules="rules" ref="formRef">
        <el-form-item label="用户姓名" prop="username">
            <el-input placeholder="请您输入用户的姓名" v-model="userParams.username"></el-input>
        </el-form-item>
        <el-form-item label="用户昵称" prop="name">
            <el-input placeholder="请您输入用户的昵称" v-model="userParams.name"></el-input>
        </el-form-item>
        <!-- 修改时没有用户密码 -->
        <el-form-item label="用户密码" prop="password" v-if="!userParams.id">
            <el-input placeholder="请您输入用户的密码" v-model="userParams.password"></el-input>
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <div style="flex: auto">
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="save">确定</el-button>
      </div>
    </template>
  </el-drawer>
  <!-- 抽屉结构：用于某一个已有账号进行职位分配 -->
  <el-drawer v-model="drawer1">
    <template #header>
      <h4>分配角色用户管理</h4>
    </template>
    <template #default>
        <el-form>
            <el-form-item label="用户姓名">
                <el-input v-model="userParams.username" :disabled="true"></el-input>
            </el-form-item>
        </el-form>
        <el-form>
            <el-form-item label="职位列表">
                <!-- checkbox多选框 -->
                <el-checkbox v-model="checkAll"   @change="handleCheckAllChange" :indeterminate="isIndeterminate">全选</el-checkbox>
                <!-- v-model="userRole" 勾上已有职位 -->
                <el-checkbox-group v-model="userRole" @change="handleCheckedCitiesChange">
                    <el-checkbox v-for="(role,index) in allRole" :key="index" :label="role">{{ role.roleName }}
                    </el-checkbox>
                </el-checkbox-group>
            </el-form-item>
        </el-form>
    </template>
    <template #footer>
      <div style="flex: auto">
        <el-button @click="drawer1=false">取消</el-button>
        <el-button type="primary" @click="confirmClick">确定</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import useLayOutSettingStore from '@/store/modules/setting';
import {ref,onMounted,reactive,nextTick} from 'vue'
import { reqUserInfo ,reqAddOrUpdateUser,reqAllRole,reqSetUserRole,reqRemoveUser,reqSelectUser} from '@/api/acl/user';
import type { UserResponseData , Records,User,AllRoleResponseData,AllRole,SetRoleData} from '@/api/acl/user/type';
import { ElMessage } from 'element-plus';
let settingStore = useLayOutSettingStore()
//默认页码
let pageNo = ref<number>(1);
//一页展示几条数据
let pageSize = ref<number>(5);
//存储用户信息数据
let userArr = ref<Records>([])
//存储用户总个数
let total = ref<number>(0)
//控制drawer的显示隐藏
let drawer = ref<boolean>(false)
//控制分配角色抽屉的显示与隐藏
let drawer1 = ref<boolean>(false)
//收集用户信息的响应式数据
let userParams = reactive<User>({
    username:'',
    name:'',
    password:''
})
//获取form组件实例
let formRef = ref<any>()
//存储全部职位
let allRole = ref<AllRole>([])
//当前用户已有职位
let userRole = ref<AllRole>([])
 const checkAll = ref(false)
//  控制复选框不确定的样式
 const isIndeterminate = ref(true)
 //准备一个数组放组合删除的id
 let deleteIdArr = ref<User[]>([])
 //定义响应式数据  收集用户输入进来的关键字
 let keyword = ref<string>('')
//获取已有的用户信息
const getHasUser = async(pager = 1)=>{
    // 默认是第一页
    pageNo.value = pager
    let result:UserResponseData = await reqUserInfo(pageNo.value,pageSize.value,keyword.value)
    if(result.code == 200){
        // console.log(result)
        userArr.value = result.data.records
        total.value = result.data.total
    }
}
//页面一挂载就发请求获取数据展示页面
onMounted(()=>{
    getHasUser()
})
//分页器下拉菜单的自定义事件的回调
const handler = ()=>{
    getHasUser()
}
//添加用户
const addUser = ()=>{
    // 显示抽屉
    drawer.value = true
    //清空数据
    Object.assign(userParams,{
          username:'',
          name:'',
          password:'',
          id:0
    })
    //清除上一次的错误提示信息
    nextTick(()=>{
        formRef.value.clearValidate('username')
        formRef.value.clearValidate('name')
        formRef.value.clearValidate('password')
    })
}
//更新用户 row是已有的用户的账户信息
const updateUser = (row:User)=>{
    // 显示抽屉
    drawer.value = true
    Object.assign(userParams,row)
        //清除上一次的错误提示信息
        nextTick(()=>{
        formRef.value.clearValidate('username')
        formRef.value.clearValidate('name')
    })
}
//保存按钮的回调
const save = async()=>{
    //点击保存 先保证表单校验全部通过
    await formRef.value.validate()
 //添加或更新
 let result:any = await reqAddOrUpdateUser(userParams)
 if(result.code ==200){
    //关闭抽屉
    drawer.value = false
    ElMessage({
      type:'success',
      message:userParams.id ? '更新成功' : '添加成功'
    })
    //获取最新的全部账户信息  修改在当前页  添加在第一页
    // getHasUser(userParams.id?pageNo.value:1)
    //浏览器自动刷新一次 目的:看有无用户信息，有-->放行，无-->回到登录页
    window.location.reload()
 }else{
     //关闭抽屉
     drawer.value = false
    ElMessage({
      type:'error',
      message:userParams.id ? '更新失败' : '添加失败'
    })
 }
}
//点击取消
const cancel = ()=>{
      //关闭抽屉
      drawer.value = false
}
// 校验用户名字回调函数
//@ts-ignore
const validatorUsername = (rule:any,value:any,callBack:any)=>{
    if(value.trim().length >= 5){
        callBack()
    }else{
        callBack(new Error('用户名字至少五位'))
    }
}
//@ts-ignore
const validatorname = (rule:any,value:any,callBack:any)=>{
    if(value.trim().length >= 5){
        callBack()
    }else{
        callBack(new Error('用户昵称至少五位'))
    }
}
//@ts-ignore
const validatorpassword = (rule:any,value:any,callBack:any)=>{
    if(value.trim().length >= 6){
        callBack()
    }else{
        callBack(new Error('密码至少六位'))
    }
}
//表单校验的规则对象
const rules = {
    username:[{required:true,trigger:'blur',validator:validatorUsername}],
    name:[{required:true,trigger:'blur',validator:validatorname}],
    password:[{required:true,trigger:'blur',validator:validatorpassword}]
}
//分配角色的回调
const setRole = async(row:User)=>{
    // 存储已有的用户信息
    Object.assign(userParams,row)
    //发请求获取全部的职位与当前用户已有职位的数据
    let result:AllRoleResponseData = await reqAllRole((userParams.id as number))
    if(result.code==200){
        allRole.value = result.data.allRolesList
        userRole.value = result.data.assignRoles
        drawer1.value = true
    }
}
const handleCheckAllChange = (val: boolean) => {
    // val  true全选  false未全选
    //如果全选了 把所有职位复制给用户已有的 
  userRole.value = val ? allRole.value : []
//   不确定样式为false
  isIndeterminate.value = false
}
const handleCheckedCitiesChange = (value: string[]) => {
    // value是各种职位对象
  const userRole = value.length
//   若勾选的个数等于所有的  则全选勾
  checkAll.value = userRole === allRole.value.length
//   不确定样式  没有全勾上不确定样式是true
  isIndeterminate.value = userRole > 0 && userRole < allRole.value.length
}

//确定按钮的回调(分配角色)
const confirmClick = async()=>{
    // 收集参数变成服务器需要的格式
    let need:SetRoleData = {
        userId: (userParams.id as number),
        roleIdList: userRole.value.map(item=>{
            return (item.id as number)
        })
        
    }
    let result:any =await reqSetUserRole(need)
    if(result.code == 200){
        ElMessage({
      type:'success',
      message:'分配成功'
       })
       drawer1.value = false
    //    更新成功留在当前页
       getHasUser(pageNo.value)
    }
}
//删除某一个用户
const deleteUser =async (userId:number)=>{
    let result = await reqRemoveUser(userId)
    if(result.code == 200){
        ElMessage({
      type:'success',
      message:'删除成功'
       })
       getHasUser(userArr.value.length>1?pageNo.value:pageNo.value-1)
    }else{
        ElMessage({
      type:'error',
      message:'删除失败'
       })
    }
}
// table事件 用于组合删除
const selectChange = (value:any)=>{
    deleteIdArr.value = value
}
//批量删除按钮的回调
const deleteSelectUser =async ()=>{
    //整理参数
   let idList:any = deleteIdArr.value.map(item=>{
    return item.id
   })
   let result:any = await reqSelectUser(idList)
   if(result.code ==200){
    ElMessage({
      type:'success',
      message:'删除成功'
       })
       getHasUser(userArr.value.length>1?pageNo.value:pageNo.value-1)
   }
}
//搜索按钮回调
const search = ()=>{
    //根据关键字获取相应的用户数据
    getHasUser()
    //清空关键字
    keyword.value = ''
}
//重置按钮
const reset = ()=>{
    settingStore.refrsh = !settingStore.refrsh
}
</script>

<style scoped>
.form {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
</style>